


using System.IO;
using System.Threading;

internal class FixedMemoryStream : Stream
{
    protected readonly long bufferlength;
    protected long length = 0;
    protected long position = 0;
    private long writeposition = 0;

    protected byte[] loopBuffer;

    internal FixedMemoryStream(long length)
    {
        bufferlength = this.length = length;
        loopBuffer = new byte[length];
    }

    public override void Flush()
    {
        //nothing to flush
    }

    public override long Seek(long offset, SeekOrigin origin)
    {
        if (origin == SeekOrigin.Begin)
        {
            position = offset;
        }
        else if (origin == SeekOrigin.End)
        {
            position = (length + offset);
        }
        else if (origin == SeekOrigin.Current)
        {
            position = (Position + offset);
        }
        position = position%bufferlength;
        return position;
    }

    public override void WriteByte(byte value)
    {
        loopBuffer[Position] = value;
        Position++;

    }

    public override void SetLength(long value)
    {

    }

    public override int Read(byte[] buffer, int offset, int count)
    {
        //Check over read
        lock (loopBuffer)
        {


            for (int i = offset; i < buffer.Length && i < count; i++)
            {
                buffer[i] = loopBuffer[Position];
                Position++;
            }

        }

        return offset + count - 1;

    }

    public override void Write(byte[] buffer, int offset, int count)
    {

        for (int i = offset; i < buffer.Length && i < count; i++)
        {
            loopBuffer[Position] = buffer[i];
            Position++;
        }
    }

    internal void WriteFrom(long fromposition, byte[] buffer, int offset, int count, bool bLock)
    {
        if (bLock)
        {
            lock (loopBuffer)
            {
                WriteBuffer(offset, buffer, count, fromposition);
            }
        }
        else
        {
            WriteBuffer(offset, buffer, count, fromposition);
        }

    }

    private void WriteBuffer(int offset, byte[] buffer, int count, long fromposition)
    {
        for (int i = offset; i < buffer.Length && i < count; i++)
        {
            loopBuffer[fromposition%bufferlength] = buffer[i];
            fromposition++;
        }
    }

    public override bool CanRead
    {
        get { return true; }
    }

    public override bool CanSeek
    {
        get { return true; }
    }

    public override bool CanWrite
    {
        get { return true; }
    }

    public override long Length
    {
        get { return length; }
    }

    public override long Position
    {
        get { return position; }
        set
        {
            position = value%bufferlength;
        }
    }
}
